﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Missbot.Common;
using Dolany.UtilityTool;
using Missbot.Core.CrossingRoute;

namespace Missbot.AIModule.OnlineStore
{
    public class HonorSvc : IDataMgr, ISingleton, IViewable
    {
        public List<DriftBottleHonor> HonorList { get; set; } = new();

        private int SumRate => FishableItems.Sum(item => item.Rate);

        public IEnumerable<DriftBottleItemModel> FishableItems => HonorList.Where(p => !p.IsLimit || p.IsCurLimit()).SelectMany(p => p.Items).ToList();

        public void RefreshData()
        {
            HonorList = DriftBottleHonorDA.Get();
        }

        public IEnumerable<DriftBottleItemModel> CurMonthLimitItems()
        {
            return HonorList.First(h => h.IsCurLimit()).Items.ToArray();
        }

        public DriftBottleItemModel FindItem(string itemName)
        {
            return HonorList.SelectMany(p => p.Items).FirstOrDefault(i => i.Name == itemName);
        }

        public DriftBottleHonor FindHonor(string honorName)
        {
            return HonorList.FirstOrDefault(h => h.Name == honorName);
        }

        public bool IsLimitItem(string itemName)
        {
            var honor = HonorList.FirstOrDefault(h => h.Items.Any(p => p.Name == itemName));
            return honor?.IsLimit ?? false;
        }

        public bool IsLimitHonor(string honorName)
        {
            var honor = HonorList.First(p => p.Name == honorName);
            return honor.IsLimit;
        }

        public static int GetItemPrice(DriftBottleItemModel item, string userID)
        {
            if (item.Rate == 0)
            {
                return 1;
            }

            var price = item.Price;
            if (OSPersonBuffDA.CheckBuff(userID, "疏雨"))
            {
                price += price * 20 / 100;
            }
            return price;
        }

        public int GetHonorPrice(string honorName, string userID)
        {
            var honor = FindHonor(honorName);
            var price = honor.Items.Sum(item => item.Rate == 0 ? 1 : item.Price) * 3 / 2;

            if (OSPersonBuffDA.CheckBuff(userID, "疏雨"))
            {
                price += price * 20 / 100;
            }
            return price;
        }

        public string FindHonorFullName(string itemName)
        {
            return HonorList.FirstOrDefault(p => p.Items.Any(i => i.Name == itemName))?.FullName();
        }

        public string FindHonorName(string itemName)
        {
            return HonorList.FirstOrDefault(p => p.Items.Any(i => i.Name == itemName))?.Name;
        }

        private DriftBottleItemModel LocalateItem(int index)
        {
            var totalSum = 0;
            foreach (var item in FishableItems)
            {
                if (index < totalSum + item.Rate)
                {
                    return item;
                }

                totalSum += item.Rate;
            }

            return FishableItems.First();
        }

        public DriftBottleItemModel RandItem()
        {
            return LocalateItem(Rander.RandInt(SumRate));
        }

        public List<DriftBottleItemModel> RandItems(int count)
        {
            var list = new List<DriftBottleItemModel>();
            for (var i = 0; i < count; i++)
            {
                list.Add(RandItem());
                Thread.Sleep(50);
            }

            return list;
        }

        public double ItemRate(DriftBottleItemModel item)
        {
            return item.Rate == 0 ? 0 : Math.Round(item.Rate * 1.0 / SumRate * 100, 2);
        }

        public IList<string> GetOrderedItemsStr(Dictionary<string, int> items)
        {
            var itemHonorDic = items.Select(i => new {Honor = FindHonor(FindHonorName(i.Key)), i.Key, i.Value})
                .GroupBy(p => p.Honor)
                .ToDictionary(p => p.Key, p => p.ToList());
            var list = itemHonorDic.Select(kv =>
                $"{kv.Key.FullName()}({kv.Value.Count}/{kv.Key.Items.Count}):{string.Join(",", kv.Value.Select(p => $"{p.Key}*{p.Value}"))}");
            return list.ToList();
        }

        public (bool canView, string viewCommand) ViewableCheck(string name)
        {
            if (FindItem(name) != null)
            {
                return (true, "查看物品");
            }

            return FindHonor(name) != null ? (true, "查看成就") : (false, null);
        }
    }
}